package ae.pcfc.cldos.online.fnp.service.client.provider;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

import javax.annotation.Resource;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.client.core.WebServiceMessageCallback;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.soap.SoapMessage;

import ae.pcfc.cldos.online.fnp.ConstantsFNP;
import ae.pcfc.cldos.online.fnp.service.client.BaseFNP;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPAccountTypeVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPCancelPaymentReqVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPCatalogVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPClientTypeVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPDebitNoteVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPFeeVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPFinalPaymentResponseVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPGeneralInfoVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPParameterVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPPaymentAdviceReqVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPPaymentAdviceRspnsVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPPrepaidTransactionVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPReportReqVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPReportResponseVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPServicePayResponseVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPServicePaymentReqTypeVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPTransReportReqVO;
import ae.pcfc.cldos.online.fnp.service.client.vo.FNPTransReportResponseVO;
import ae.pcfc.cldos.online.fnp.service.types.AccountType;
import ae.pcfc.cldos.online.fnp.service.types.BlockAmountRequest;
import ae.pcfc.cldos.online.fnp.service.types.BlockAmountResponse;
import ae.pcfc.cldos.online.fnp.service.types.CancelPaymentAdviceRequest;
import ae.pcfc.cldos.online.fnp.service.types.CancelPaymentAdviceResponse;
import ae.pcfc.cldos.online.fnp.service.types.ClientTransactionType;
import ae.pcfc.cldos.online.fnp.service.types.ClientType;
import ae.pcfc.cldos.online.fnp.service.types.EnquireDepositTransactionsRequest;
import ae.pcfc.cldos.online.fnp.service.types.EnquireDepositTransactionsResponse;
import ae.pcfc.cldos.online.fnp.service.types.EnquireDepositsRequest;
import ae.pcfc.cldos.online.fnp.service.types.EnquireDepositsResponse;
import ae.pcfc.cldos.online.fnp.service.types.FeeType;
import ae.pcfc.cldos.online.fnp.service.types.FinalizePaymentRequest;
import ae.pcfc.cldos.online.fnp.service.types.FinalizePaymentResponse;
import ae.pcfc.cldos.online.fnp.service.types.GeneratePaymentAdviceRequest;
import ae.pcfc.cldos.online.fnp.service.types.GeneratePaymentAdviceResponse;
import ae.pcfc.cldos.online.fnp.service.types.GetClientPrepaidAccountReportRequest;
import ae.pcfc.cldos.online.fnp.service.types.GetClientPrepaidAccountReportResponse;
import ae.pcfc.cldos.online.fnp.service.types.GetClientReservedAccountReportRequest;
import ae.pcfc.cldos.online.fnp.service.types.GetClientReservedAccountReportResponse;
import ae.pcfc.cldos.online.fnp.service.types.GetClientTransactionRequest;
import ae.pcfc.cldos.online.fnp.service.types.GetClientTransactionResponse;
import ae.pcfc.cldos.online.fnp.service.types.GetServiceCatalogueRequest;
import ae.pcfc.cldos.online.fnp.service.types.GetServiceCatalogueResponse;
import ae.pcfc.cldos.online.fnp.service.types.GetServiceCatalogueResponse.Service;
import ae.pcfc.cldos.online.fnp.service.types.GetServiceParametersRequest;
import ae.pcfc.cldos.online.fnp.service.types.GetServiceParametersResponse;
import ae.pcfc.cldos.online.fnp.service.types.PrepaidTransaction;
import ae.pcfc.cldos.online.fnp.service.types.PreviewPaymentAdviceRequest;
import ae.pcfc.cldos.online.fnp.service.types.PreviewPaymentAdviceResponse;
import ae.pcfc.cldos.online.fnp.service.types.ServiceParameterType;
import ae.pcfc.cldos.online.fnp.service.types.ServicePaymentRequestType;
import ae.pcfc.cldos.online.fnp.service.types.ServicePaymentResponseType;
import ae.pcfc.cldos.online.fnp.service.types.UnblockAmountRequest;
import ae.pcfc.cldos.online.fnp.service.types.UnblockAmountResponse;

public abstract class BaseFNPImpl implements BaseFNP {

	protected WebServiceTemplate wsTemplateFNP;
	protected String formsAppURLFNP;
	
	@Value("${FinanceNPaymentFNP}")
	String classURIValue = ConstantsFNP.FNP_WS_ENDPOINT;
	


	/**
	 * @param formsAppURL the formsAppURL to set
	 */
	@Resource(name = "formsAppURLFNP")
	public void setFormsAppURLFNP(String formsAppURLFNP) {
		this.formsAppURLFNP = formsAppURLFNP;
	}
	/**
	 * @param wsTemplateFNP
	 *            the wsTemplateFNP to set
	 */
	@Resource(name = "wsTemplateFNP")
	public void setWsTemplateFNP(WebServiceTemplate wsTemplateFNP) {
		this.wsTemplateFNP = wsTemplateFNP;
	}
	
	
	private static DatatypeFactory df = null;     
	static {         
		try {             
			df = DatatypeFactory.newInstance();         
		} catch (DatatypeConfigurationException dce) {             
			throw new IllegalStateException(                 
					"Exception while obtaining DatatypeFactory instance", dce);         
		}     
	}        
	/*** Converts a java.util.Date into an instance of XMLGregorianCalendar      *      * 
	@param date Instance of java.util.Date or a null reference      
	* @return XMLGregorianCalendar instance whose value is based upon the      
	*  value in the date parameter. If the date parameter is null then      *  this method will simply return null.      */    
	public static XMLGregorianCalendar asXMLGregorianCalendar(java.util.Date date) {
		if (date == null) {
			return null;
		} else {
			GregorianCalendar gc = new GregorianCalendar();
			gc.setTimeInMillis(date.getTime());
			return df.newXMLGregorianCalendar(gc);
		}
	} 
	/* (non-Javadoc)
	 * @see ae.pcfc.cldos.online.fnp.service.client.BaseFNP#retreiveFNPCatalog()
	 * 
	 */
	/**
	 * @param none
	 * @author akhader
	 * @return  List<FNPCatalogVO>
	 * method to fetch the catalog desc from FNp through web service
	 */
	@SuppressWarnings("unchecked")
	public List<FNPCatalogVO> retreiveFNPCatalog(List<String> fnpServiceCodeList){
		List fnpCatalogs= new ArrayList<ae.pcfc.cldos.online.fnp.service.client.vo.FNPCatalogVO>();
		//String classURIValue = ConstantsFNP.FNP_WS_ENDPOINT;
		//setting the parameters
		GetServiceCatalogueRequest catReq = new GetServiceCatalogueRequest();
		catReq.setSource(ConstantsFNP.FNP_SOURCE);  
		catReq.setCategory(ConstantsFNP.FNP_FETCH_ARG);
		//calling the FNP getcatalog method
		GetServiceCatalogueResponse response = (GetServiceCatalogueResponse) wsTemplateFNP
				.marshalSendAndReceive(classURIValue,catReq,
						new WebServiceMessageCallback() {
							public void doWithMessage(WebServiceMessage message) {
								((SoapMessage) message)
										.setSoapAction(ConstantsFNP.GET_CATALOG_SOAP_ACTION_GET_CATALOG);
							}
						});
		List<Service> serviceList = response.getService();
		//storing it in CLD VOs
		if(serviceList!=null && serviceList.size()!=0){
			for(int i=0; i<serviceList.size(); i++){
				Service service = serviceList.get(i);
				System.out.println(service.getCode()+">>>"+service.getId()+">>>"+service.getDescriptionEn()+"/n");
				if(fnpServiceCodeList==null || fnpServiceCodeList.contains(service.getCode())){
					FNPCatalogVO fNPCatalogVO  = new FNPCatalogVO();
					fNPCatalogVO.setCode(service.getCode());
					fNPCatalogVO.setDescArb(service.getDescriptionAr());
					fNPCatalogVO.setDescEng(service.getDescriptionEn());
					fNPCatalogVO.setId(service.getId());
					fnpCatalogs.add(fNPCatalogVO);
				}
			}
		}
		return fnpCatalogs;
	}
	/* (non-Javadoc)
	 * @see ae.pcfc.cldos.online.fnp.service.client.BaseFNP#retreiveFNPCatalog()
	 * 
	 */
	/**
	 * @param none
	 * @author akhader
	 * @return  List<FNPCatalogVO>
	 * method to fetch the parameter  from FNp through web service
	 */
	@SuppressWarnings("unchecked")
	public List<FNPParameterVO> retreiveFNPParameters(List<String> serviceIdList){
		List fnpParams= new ArrayList<FNPParameterVO>();
		//setting the parameters
		GetServiceParametersRequest getServParams = new GetServiceParametersRequest();
		getServParams.setSource(ConstantsFNP.FNP_SOURCE);
		getServParams.getServiceIdList().addAll(serviceIdList);
		//calling the FNP getparameters method
			GetServiceParametersResponse response = (GetServiceParametersResponse) wsTemplateFNP
			.marshalSendAndReceive(classURIValue,getServParams,
					new WebServiceMessageCallback() {
				public void doWithMessage(WebServiceMessage message) {
					((SoapMessage) message)
					.setSoapAction(ConstantsFNP.GET_CATALOG_SOAP_ACTION_GET_PARAM);
				}
			});

			List<GetServiceParametersResponse.Service> serviceList = response.getService();
			//storing it in CLD VOs
			if(serviceList!=null && serviceList.size()!=0){
				for(int i=0; i<serviceList.size();i++){
					GetServiceParametersResponse.Service service = serviceList.get(i);
					List<ServiceParameterType> servParamTypes = service.getServiceParameter();
					if(servParamTypes!=null && servParamTypes.size()!=0){
						for(ServiceParameterType serviceParameterType : servParamTypes){
							FNPParameterVO fnpParameterVO  = new FNPParameterVO();
							fnpParameterVO.setServiceId(service.getServiceId());
							fnpParameterVO.setOrder(serviceParameterType.getOrder());
							fnpParameterVO.setName(serviceParameterType.getName());
							fnpParameterVO.setValue(serviceParameterType.getValue());
							fnpParams.add(fnpParameterVO);
						}
					}
				}
			}
		
		return fnpParams;
	}
	/**
	 * @param none
	 * @author akhader
	 * @return  List<FNPCatalogVO>
	 * method to fetch the catalog desc from FNp through web service
	 */
	@SuppressWarnings("unchecked")
	public FNPPaymentAdviceRspnsVO generatePaymentAdvice(FNPPaymentAdviceReqVO fnpPaymentAdviceReqVO){
		FNPPaymentAdviceRspnsVO fnpPaymentAdviceRspnsVO = new FNPPaymentAdviceRspnsVO();
		//setting the parameters
		GeneratePaymentAdviceRequest generatePaymentAdviceRequest = new GeneratePaymentAdviceRequest();
		//setting the client info
		ClientType clientType = new ClientType();
		FNPClientTypeVO fnpClientTypeVO  = fnpPaymentAdviceReqVO.getFnpClientTypeVO();
		clientType.setId(fnpClientTypeVO.getId());
		clientType.setLicenseNumber(fnpClientTypeVO.getLicenseNumber());
		clientType.setNameAr(fnpClientTypeVO.getNameAr());
		clientType.setNameEn(fnpClientTypeVO.getNameEn());
		generatePaymentAdviceRequest.setClient(clientType);
		//setting serviceid and params
		List<FNPServicePaymentReqTypeVO> fnpServicePaymentReqTypeVOs = fnpPaymentAdviceReqVO.getFnpServicePaymentReqTypeVOs();
		for(int i=0; i<fnpServicePaymentReqTypeVOs.size();i++){
			FNPServicePaymentReqTypeVO fnpServicePaymentReqTypeVO = fnpServicePaymentReqTypeVOs.get(i);
			ServicePaymentRequestType servicePaymentRequestType = new ServicePaymentRequestType();
			servicePaymentRequestType.setId(fnpServicePaymentReqTypeVO.getServiceId());
			servicePaymentRequestType.setQuantity(fnpServicePaymentReqTypeVO.getQuantity());
			List<FNPParameterVO> fnpParams = fnpServicePaymentReqTypeVO.getFnpParams();
			List<ServiceParameterType> serviceParams = new ArrayList<ServiceParameterType>();
			if(fnpParams!=null && fnpParams.size()!=0){
				for(FNPParameterVO fnpParameterVO:fnpParams){
					ServiceParameterType serviceParameterType = new ServiceParameterType();
					serviceParameterType.setName(fnpParameterVO.getName());
					serviceParameterType.setOrder(fnpParameterVO.getOrder());
					serviceParameterType.setValue(fnpParameterVO.getValue());
					serviceParams.add(serviceParameterType);
				}
			}
			servicePaymentRequestType.getServiceParameter().addAll(serviceParams);
			generatePaymentAdviceRequest.getServiceList().add(servicePaymentRequestType);
			
		}
		//setting other payment req advice params
		generatePaymentAdviceRequest.setExpiryDate(null);
		generatePaymentAdviceRequest.setRemarks(fnpPaymentAdviceReqVO.getRemarks());
		generatePaymentAdviceRequest.setSource(ConstantsFNP.FNP_SOURCE);
		generatePaymentAdviceRequest.setTransactionNumber(fnpPaymentAdviceReqVO.getTransactionNumber());
		generatePaymentAdviceRequest.setTransactionRemarks(fnpPaymentAdviceReqVO.getTransactionRemarks());
		generatePaymentAdviceRequest.setUserName(fnpPaymentAdviceReqVO.getUserName());
		//calling web service

			GeneratePaymentAdviceResponse response = (GeneratePaymentAdviceResponse) wsTemplateFNP
			.marshalSendAndReceive(classURIValue,generatePaymentAdviceRequest,
					new WebServiceMessageCallback() {
				public void doWithMessage(WebServiceMessage message) {
					((SoapMessage) message)
					.setSoapAction(ConstantsFNP.GET_CATALOG_SOAP_ACTION_GENERATE_PAYMNT_ADVICE);
				}
			});
			//storing response  in CLD VOs
			if(response!=null){
				fnpPaymentAdviceRspnsVO.setSettled(response.isIsSettled());
				fnpPaymentAdviceRspnsVO.setPaymentAdviceAmount(response.getPaymentAdviceAmount());
				fnpPaymentAdviceRspnsVO.setPaymentAdviceNumber(response.getPaymentAdviceNumber());
				fnpPaymentAdviceRspnsVO.setPaymentAdvicePDF(response.getPaymentAdvicePDF());
				fnpPaymentAdviceRspnsVO.setPaymentAdviceStatus(response.getPaymentAdviceStatus());
				fnpPaymentAdviceRspnsVO.setReferenceNumber(response.getReferenceNumber());
			}

		return fnpPaymentAdviceRspnsVO;
	}
	/* (non-Javadoc)
	 * @see ae.pcfc.cldos.online.fnp.service.client.BaseFNP#retreiveFNPCatalog(java.util.List)
	 */
	/**
	 * @param none
	 * @author akhader
	 * @return  List<FNPCatalogVO>
	 * method to fetch the catalog desc from FNp through web service
	 */
	@SuppressWarnings("unchecked")
	public FNPAccountTypeVO enquireDeposits(String clentId){
		FNPAccountTypeVO fNPAccountTypeVO = new FNPAccountTypeVO();
		//String classURIValue = ConstantsFNP.FNP_WS_ENDPOINT;
		//setting the parameters
		EnquireDepositsRequest enquireDepositsRequest = new EnquireDepositsRequest();
		enquireDepositsRequest.setSource(ConstantsFNP.FNP_SOURCE);  
		enquireDepositsRequest.setClientId(clentId);
		//calling the FNP getcatalog method
		EnquireDepositsResponse response = (EnquireDepositsResponse) wsTemplateFNP
				.marshalSendAndReceive(classURIValue,enquireDepositsRequest,
						new WebServiceMessageCallback() {
							public void doWithMessage(WebServiceMessage message) {
								((SoapMessage) message)
										.setSoapAction(ConstantsFNP.GET_CATALOG_SOAP_ACTION_ENQUIRE_DEPOSITS);
							}
						});
		AccountType accountType = response.getAccount();
		//storing it in CLD VOs
		if(accountType!=null){
			fNPAccountTypeVO.setPrepaidAccBalance(accountType.getPrepaidAccBalance());
			fNPAccountTypeVO.setReservedAccBalance(accountType.getReservedAccBalance());
			fNPAccountTypeVO.setId(accountType.getId());
		}
		return fNPAccountTypeVO;
	}
	///
	/**
	 * @param none
	 * @author akhader
	 * @return  boolean
	 * method to block amount afetr payment advice
	 */
	@SuppressWarnings("unchecked")
	public boolean blockAmount(FNPGeneralInfoVO fnpBlockUnBlockAmountVO){
		//setting the parameters
		boolean flag=false;
		BlockAmountRequest blockAmountRequest = new BlockAmountRequest();
		blockAmountRequest.setClientId(fnpBlockUnBlockAmountVO.getClientId());
		blockAmountRequest.setPaymentAdviceNumber(fnpBlockUnBlockAmountVO.getPaymentAdviceNumber());
		blockAmountRequest.setSource(ConstantsFNP.FNP_SOURCE);
		blockAmountRequest.setTransactionNumber(fnpBlockUnBlockAmountVO.getTransactionNumber());
		blockAmountRequest.setTransactionRemarks(fnpBlockUnBlockAmountVO.getTransactionRemarks());
		blockAmountRequest.setUserName(fnpBlockUnBlockAmountVO.getUserName());
		//calling the FNP getcatalog method
			BlockAmountResponse response = (BlockAmountResponse) wsTemplateFNP
				.marshalSendAndReceive(classURIValue,blockAmountRequest,
						new WebServiceMessageCallback() {
							public void doWithMessage(WebServiceMessage message) {
								((SoapMessage) message)
										.setSoapAction(ConstantsFNP.GET_CATALOG_SOAP_ACTION_BLOCK_AMOUNT);
							}
						});
			flag=true;

		return flag;
	}
	/**
	 * @param none
	 * @author akhader
	 * @return  boolean
	 * method to unblock amount after cancel/reject
	 */
	@SuppressWarnings("unchecked")
	public boolean unblockAmount(FNPGeneralInfoVO fnpBlockUnBlockAmountVO){
		//setting the parameters
		boolean flag=false;
		UnblockAmountRequest unblockAmountRequest = new UnblockAmountRequest();
		unblockAmountRequest.setClientId(fnpBlockUnBlockAmountVO.getClientId());
		unblockAmountRequest.setPaymentAdviceNumber(fnpBlockUnBlockAmountVO.getPaymentAdviceNumber());
		unblockAmountRequest.setSource(ConstantsFNP.FNP_SOURCE);
		assert(unblockAmountRequest.getTransactionNumber()!=null);
		unblockAmountRequest.setTransactionNumber(fnpBlockUnBlockAmountVO.getTransactionNumber());
		//unblockAmountRequest.setTransactionNumber(fnpBlockUnBlockAmountVO.getTransactionNumber());
		unblockAmountRequest.setTransactionRemarks(fnpBlockUnBlockAmountVO.getTransactionRemarks());
		unblockAmountRequest.setUserName(fnpBlockUnBlockAmountVO.getUserName());
		//calling the FNP getcatalog method
		try{	
		UnblockAmountResponse response = (UnblockAmountResponse) wsTemplateFNP
				.marshalSendAndReceive(classURIValue,unblockAmountRequest,
						new WebServiceMessageCallback() {
							public void doWithMessage(WebServiceMessage message) {
								((SoapMessage) message)
										.setSoapAction(ConstantsFNP.GET_CATALOG_SOAP_ACTION_UNBLOCK_AMOUNT);
							}
						});
		}catch (Exception e) {
			e.printStackTrace();
		}
			flag=true;
		
		return flag;
	}
	/**
	 * @param none
	 * @author akhader
	 * @return  FNPFinalPaymentResponseVO
	 * method to finalize the payment after back office approval
	 */
	@SuppressWarnings("unchecked")
	public FNPFinalPaymentResponseVO finalizePayment(FNPGeneralInfoVO fnpGeneralInfoVO){
		//setting the parameters
		FNPFinalPaymentResponseVO finalPaymentResponseVO = null;
		FinalizePaymentRequest finalizePaymentRequest = new FinalizePaymentRequest();
		ClientType clientType = new ClientType();
		clientType.setId(fnpGeneralInfoVO.getFnpClientTypeVO().getId());
		clientType.setLicenseNumber(fnpGeneralInfoVO.getFnpClientTypeVO().getLicenseNumber());
		clientType.setNameAr(fnpGeneralInfoVO.getFnpClientTypeVO().getNameAr());
		clientType.setNameEn(fnpGeneralInfoVO.getFnpClientTypeVO().getNameEn());
		finalizePaymentRequest.setClient(clientType);
		finalizePaymentRequest.setPaymentAdviceNumber(fnpGeneralInfoVO.getPaymentAdviceNumber());
		finalizePaymentRequest.setSource(ConstantsFNP.FNP_SOURCE);
		assert(fnpGeneralInfoVO.getTransactionNumber()!=null);
		finalizePaymentRequest.setTransactionNumber(fnpGeneralInfoVO.getTransactionNumber());
		finalizePaymentRequest.setTransactionRemarks(fnpGeneralInfoVO.getTransactionRemarks());
		finalizePaymentRequest.setUserName(fnpGeneralInfoVO.getUserName());
		//calling the FNP getcatalog method
			FinalizePaymentResponse response = (FinalizePaymentResponse) wsTemplateFNP
				.marshalSendAndReceive(classURIValue,finalizePaymentRequest,
						new WebServiceMessageCallback() {
							public void doWithMessage(WebServiceMessage message) {
								((SoapMessage) message)
										.setSoapAction(ConstantsFNP.GET_CATALOG_SOAP_ACTION_FINALIZE_PAYMENT);
							}
						});
			if(response!=null){
				finalPaymentResponseVO = new FNPFinalPaymentResponseVO();
				finalPaymentResponseVO.setReferenceNo(response.getReferenceNumber());
				FNPDebitNoteVO fNPDebitNoteVO = new FNPDebitNoteVO();
				fNPDebitNoteVO.setDebitNoteAmount(response.getDebitNoteAmount());
				fNPDebitNoteVO.setDebitNoteId(response.getDebitNoteId());
				fNPDebitNoteVO.setDebitNotePDF(response.getDebitNotePDF());
				fNPDebitNoteVO.setDebitNoteStatus(response.getDebitNoteStatus());
				fNPDebitNoteVO.setPaymentAdviceId(response.getPaymentAdviceId());
				finalPaymentResponseVO.setfNPDebitNoteVO(fNPDebitNoteVO);
			}
		
		return finalPaymentResponseVO;
	}
	/**
	 * @param none
	 * @author akhader
	 * @return  boolean
	 * method to cancel the payment after back office cancel/reject
	 */
	@SuppressWarnings("unchecked")
	public boolean cancelPayment(FNPCancelPaymentReqVO fnpCancelPaymentReqVO){
		//setting the parameters
		boolean flag = false;
		CancelPaymentAdviceRequest cancelPaymentAdviceRequest = new CancelPaymentAdviceRequest();
		cancelPaymentAdviceRequest.setPaymentAdviceNumber(fnpCancelPaymentReqVO.getPaymentAdviceNumber());
		cancelPaymentAdviceRequest.setSource(ConstantsFNP.FNP_SOURCE);
		assert(cancelPaymentAdviceRequest.getTransactionNumber()!=null);
		cancelPaymentAdviceRequest.setTransactionNumber(fnpCancelPaymentReqVO.getTransactionNumber());
		cancelPaymentAdviceRequest.setUserName(fnpCancelPaymentReqVO.getUserName());
		//calling the FNP getcatalog method
			CancelPaymentAdviceResponse response = (CancelPaymentAdviceResponse) wsTemplateFNP
				.marshalSendAndReceive(classURIValue,cancelPaymentAdviceRequest,
						new WebServiceMessageCallback() {
							public void doWithMessage(WebServiceMessage message) {
								((SoapMessage) message)
										.setSoapAction(ConstantsFNP.GET_CATALOG_SOAP_ACTION_CANCEL_PAYMENT);
							}
						});
			if(response!=null){
				flag=true;
			}
		
		return flag;
	}
	/**
	 * @param none
	 * @author akhader
	 * @return  List<FNPCatalogVO>
	 * method to fetch the catalog desc from FNp through web service
	 */
	public FNPPaymentAdviceRspnsVO previewPaymentAdvice(FNPPaymentAdviceReqVO fnpPaymentAdviceReqVO){
		FNPPaymentAdviceRspnsVO fnpPaymentAdviceRspnsVO = new FNPPaymentAdviceRspnsVO();
		//setting the parameters
		PreviewPaymentAdviceRequest previewPaymentAdviceRequest = new PreviewPaymentAdviceRequest();
		//setting the client info
		ClientType clientType = new ClientType();
		FNPClientTypeVO fnpClientTypeVO  = fnpPaymentAdviceReqVO.getFnpClientTypeVO();
		clientType.setId(fnpClientTypeVO.getId());
		clientType.setLicenseNumber(fnpClientTypeVO.getLicenseNumber());
		clientType.setNameAr(fnpClientTypeVO.getNameAr());
		clientType.setNameEn(fnpClientTypeVO.getNameEn());
		previewPaymentAdviceRequest.setClient(clientType);
		//setting serviceid and params
		List<FNPServicePaymentReqTypeVO> fnpServicePaymentReqTypeVOs = fnpPaymentAdviceReqVO.getFnpServicePaymentReqTypeVOs();
		for(int i=0; i<fnpServicePaymentReqTypeVOs.size();i++){
			FNPServicePaymentReqTypeVO fnpServicePaymentReqTypeVO = fnpServicePaymentReqTypeVOs.get(i);
			ServicePaymentRequestType servicePaymentRequestType = new ServicePaymentRequestType();
			servicePaymentRequestType.setId(fnpServicePaymentReqTypeVO.getServiceId());
			servicePaymentRequestType.setQuantity(fnpServicePaymentReqTypeVO.getQuantity());
			List<FNPParameterVO> fnpParams = fnpServicePaymentReqTypeVO.getFnpParams();
			List<ServiceParameterType> serviceParams = new ArrayList<ServiceParameterType>();
			if(fnpParams!=null && fnpParams.size()!=0){
				for(FNPParameterVO fnpParameterVO:fnpParams){
					ServiceParameterType serviceParameterType = new ServiceParameterType();
					serviceParameterType.setName(fnpParameterVO.getName());
					//serviceParameterType.setOrder(fnpParameterVO.getOrder());
					serviceParameterType.setValue(fnpParameterVO.getValue());
					serviceParams.add(serviceParameterType);
				}
			}
			servicePaymentRequestType.getServiceParameter().addAll(serviceParams);
			previewPaymentAdviceRequest.getServiceList().add(servicePaymentRequestType);
			
		}
		//setting other payment req advice params
		previewPaymentAdviceRequest.setExpiryDate(null);
		previewPaymentAdviceRequest.setRemarks(fnpPaymentAdviceReqVO.getRemarks());
		previewPaymentAdviceRequest.setSource(ConstantsFNP.FNP_SOURCE);
		//calling web service
			PreviewPaymentAdviceResponse response = (PreviewPaymentAdviceResponse) wsTemplateFNP
			.marshalSendAndReceive(classURIValue,previewPaymentAdviceRequest,
					new WebServiceMessageCallback() {
				public void doWithMessage(WebServiceMessage message) {
					((SoapMessage) message)
					.setSoapAction(ConstantsFNP.GET_CATALOG_SOAP_ACTION_PREVIEW_PAYMENT_ADVICE);
				}
			});
			//storing response  in CLD VOs
			if(response!=null){
				fnpPaymentAdviceRspnsVO.setSettled(response.isIsSettled());
				fnpPaymentAdviceRspnsVO.setPaymentAdviceAmount(response.getPaymentAdviceAmount());
				fnpPaymentAdviceRspnsVO.setPaymentAdviceStatus(response.getPaymentAdviceStatus());
				if(response.getServiceList()!=null && response.getServiceList().size()!=0){
					List<FNPServicePayResponseVO> servicePays = new ArrayList<FNPServicePayResponseVO>();
					for(ServicePaymentResponseType servicePaymentResponseType :response.getServiceList()){
						FNPServicePayResponseVO fNPServicePayResponseVO = new FNPServicePayResponseVO();
						fNPServicePayResponseVO.setDisplayFeeItems(servicePaymentResponseType.getDisplayFeeItems());
						fNPServicePayResponseVO.setQuantity(servicePaymentResponseType.getQuantity());
						fNPServicePayResponseVO.setSeriveAmount(servicePaymentResponseType.getSeriveAmount());
						fNPServicePayResponseVO.setServiceId(servicePaymentResponseType.getId());
						if(servicePaymentResponseType.getFeeList()!=null && servicePaymentResponseType.getFeeList().size()!=0){
							List<FNPFeeVO> feeList = new ArrayList<FNPFeeVO>();
							for(FeeType feeType:servicePaymentResponseType.getFeeList()){
								FNPFeeVO feeVO = new FNPFeeVO();
								feeVO.setAmount(feeType.getAmount());
								feeVO.setDescriptionArb(feeType.getDescriptionAr());
								feeVO.setDescriptionEn(feeType.getDescriptionEn());
								feeVO.setId(feeType.getId());
								feeList.add(feeVO);
							}
							fNPServicePayResponseVO.setFeeList(feeList);
						}
						servicePays.add(fNPServicePayResponseVO);
					}
					fnpPaymentAdviceRspnsVO.setServicePaymntResponeList(servicePays);
				}
			}

		return fnpPaymentAdviceRspnsVO;
	}
	
	/**
	 * @param clientId
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<FNPPrepaidTransactionVO> enquireDepositTransaction(String clientId, Date startDate, Date endDate){
		//setting the parameters
		List<FNPPrepaidTransactionVO> fnpTransactionVos = new ArrayList<FNPPrepaidTransactionVO>();
		EnquireDepositTransactionsRequest enquireDepositTransactionsRequest = new EnquireDepositTransactionsRequest();
		enquireDepositTransactionsRequest.setClientId(clientId);
		enquireDepositTransactionsRequest.setEndDate(asXMLGregorianCalendar(endDate));
		enquireDepositTransactionsRequest.setSource(ConstantsFNP.FNP_SOURCE);
		enquireDepositTransactionsRequest.setStartDate(asXMLGregorianCalendar(startDate));
		
		//calling the FNP getcatalog method
		EnquireDepositTransactionsResponse response = (EnquireDepositTransactionsResponse) wsTemplateFNP
				.marshalSendAndReceive(classURIValue,enquireDepositTransactionsRequest,
						new WebServiceMessageCallback() {
							public void doWithMessage(WebServiceMessage message) {
								((SoapMessage) message)
										.setSoapAction(ConstantsFNP.GET_CATALOG_SOAP_ACTION_FINP_TRANSACTIONS);
							}
						});
		if(response.getPrepaidTransaction()!=null && response.getPrepaidTransaction().size()!=0){
			for(PrepaidTransaction prepaidTransaction :response.getPrepaidTransaction() ){
				FNPPrepaidTransactionVO fnpPrepaidTransactionVO = new FNPPrepaidTransactionVO();
				fnpPrepaidTransactionVO.setAuditDate(prepaidTransaction.getAuditDate());
				fnpPrepaidTransactionVO.setAuditGroupId(prepaidTransaction.getAuditGroupId());
				fnpPrepaidTransactionVO.setDepositAmount(prepaidTransaction.getDepositAmount());
				fnpPrepaidTransactionVO.setReservedAmount(prepaidTransaction.getReservedAmount());
				fnpPrepaidTransactionVO.setTrAmount(prepaidTransaction.getTrAmount());
				fnpPrepaidTransactionVO.setTrMode(prepaidTransaction.getTrMode());
				fnpPrepaidTransactionVO.setTrReference(prepaidTransaction.getTrReference());
				fnpPrepaidTransactionVO.setTrRemarks(prepaidTransaction.getTrRemarks());
				fnpPrepaidTransactionVO.setTrSourceId(prepaidTransaction.getTrSourceId());
				fnpPrepaidTransactionVO.setTrSourceUser(prepaidTransaction.getTrSourceUser());
				fnpTransactionVos.add(fnpPrepaidTransactionVO);
			}
		}
			
		return fnpTransactionVos;
	}
	
	/**
	 * @param fnpReportReqVO
	 * @return FNPReportResponseVO
	 */
	@SuppressWarnings("unchecked")
	public FNPReportResponseVO generateClientAccountReport(FNPReportReqVO fnpReportReqVO){
		//setting the parameters
		FNPReportResponseVO fnpReportResponseVO = new FNPReportResponseVO();
		//calling the FNP getClientPrepaidAccountReport method
		if(fnpReportReqVO.isActual()){
			GetClientPrepaidAccountReportRequest getClientPrepaidAccountReportRequest = new GetClientPrepaidAccountReportRequest();
			getClientPrepaidAccountReportRequest.setEndDate(asXMLGregorianCalendar(fnpReportReqVO.getEndDate()));
			getClientPrepaidAccountReportRequest.setExportOption(fnpReportReqVO.getType());
			getClientPrepaidAccountReportRequest.setSource(ConstantsFNP.FNP_SOURCE);
			getClientPrepaidAccountReportRequest.setStartDate(asXMLGregorianCalendar(fnpReportReqVO.getStartDate()));
			getClientPrepaidAccountReportRequest.setTrakheesId(fnpReportReqVO.getTrakheesID());
			GetClientPrepaidAccountReportResponse response = (GetClientPrepaidAccountReportResponse) wsTemplateFNP
				.marshalSendAndReceive(classURIValue,getClientPrepaidAccountReportRequest,
						new WebServiceMessageCallback() {
							public void doWithMessage(WebServiceMessage message) {
								((SoapMessage) message)
										.setSoapAction(ConstantsFNP.GET_CATALOG_SOAP_ACTION_CLIENT_PREPAID_ACCOUNT);
							}
						});
			if(response!=null){
				fnpReportResponseVO.setReportPDF(response.getClientPrepaidAccountReportPDF());
			}
		}else{
			GetClientReservedAccountReportRequest getClientReservedAccountReportRequest = new GetClientReservedAccountReportRequest();
			getClientReservedAccountReportRequest.setEndDate(asXMLGregorianCalendar(fnpReportReqVO.getEndDate()));
			getClientReservedAccountReportRequest.setExportOption(fnpReportReqVO.getType());
			getClientReservedAccountReportRequest.setSource(ConstantsFNP.FNP_SOURCE);
			getClientReservedAccountReportRequest.setStartDate(asXMLGregorianCalendar(fnpReportReqVO.getStartDate()));
			getClientReservedAccountReportRequest.setTrakheesId(fnpReportReqVO.getTrakheesID());
			GetClientReservedAccountReportResponse response = (GetClientReservedAccountReportResponse) wsTemplateFNP
					.marshalSendAndReceive(classURIValue,getClientReservedAccountReportRequest,
							new WebServiceMessageCallback() {
								public void doWithMessage(WebServiceMessage message) {
									((SoapMessage) message)
											.setSoapAction(ConstantsFNP.GET_CATALOG_SOAP_ACTION_CLIENT_RESERVE_ACCOUNT);
								}
							});
				if(response!=null){
					fnpReportResponseVO.setReportPDF(response.getClientPrepaidAccountReportPDF());
				}
		}
		return fnpReportResponseVO;
	}
	
	/**
	 * @param fnpTransReportReqVO
	 * @return
	 */
	public List<FNPTransReportResponseVO> retreiveFNPTransactionReport(FNPTransReportReqVO fnpTransReportReqVO){
		List<FNPTransReportResponseVO> transReportList= new ArrayList<FNPTransReportResponseVO>();
		//setting the parameters
		GetClientTransactionRequest clientTransactionRequest = new GetClientTransactionRequest();
		clientTransactionRequest.setSource(ConstantsFNP.FNP_SOURCE);  
		clientTransactionRequest.setStartDate(asXMLGregorianCalendar(fnpTransReportReqVO.getStartDate()));
		clientTransactionRequest.setEndDate(asXMLGregorianCalendar(fnpTransReportReqVO.getEndDate()));
		clientTransactionRequest.setClientId(fnpTransReportReqVO.getTrakheesID());
		
		//calling the FNP getcatalog method
		GetClientTransactionResponse response = (GetClientTransactionResponse) wsTemplateFNP
				.marshalSendAndReceive(classURIValue,clientTransactionRequest,
						new WebServiceMessageCallback() {
							public void doWithMessage(WebServiceMessage message) {
								((SoapMessage) message)
										.setSoapAction(ConstantsFNP.GET_CATALOG_SOAP_ACTION_TRANSACTION_REPORT);
							}
						});
		List<ClientTransactionType> clientTransactionList = response.getClientTransaction();
		//storing it in CLD VOs
		if(clientTransactionList!=null){
			for(ClientTransactionType clientTransactionType :clientTransactionList){
				FNPTransReportResponseVO fnpTransReportResponseVO = new FNPTransReportResponseVO();
				fnpTransReportResponseVO.setPaymentAdviceAmount(clientTransactionType.getPaymentAdvice().getAmount());
				fnpTransReportResponseVO.setTransactionNumber(clientTransactionType.getPaymentAdvice().getTrNumber());
				fnpTransReportResponseVO.setPaymentAdviceId(clientTransactionType.getPaymentAdvice().getPaymentAdviceId());
				if(clientTransactionType.getReciepts() != null && clientTransactionType.getReciepts().getReceipt() !=null && clientTransactionType.getReciepts().getReceipt().size()!=0){
					fnpTransReportResponseVO.setReceiptNo(clientTransactionType.getReciepts().getReceipt().get(0).getReceiptNumber());
				}
				if(clientTransactionType.getDebitNotes() != null && clientTransactionType.getDebitNotes().getDebitNote() !=null && clientTransactionType.getDebitNotes().getDebitNote().size()!=0){
					fnpTransReportResponseVO.setDebitNoteNo(clientTransactionType.getDebitNotes().getDebitNote().get(0).getDebitNoteNumber());
					fnpTransReportResponseVO.setReceiptNo(clientTransactionType.getDebitNotes().getDebitNote().get(0).getDebitNoteNumber());
				}
				transReportList.add(fnpTransReportResponseVO);
			}
		}
		return transReportList;
	}

}
